﻿using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

/// <summary>
/// 备注：tmoon
/// </summary>
public class Packager
{
    private static List<string> paths = new List<string>();
    private static List<string> files = new List<string>();
    private static List<AssetBundleBuild> maps = new List<AssetBundleBuild>();

    [MenuItem("Build/Build iPhone Resource", false, 100)]
    private static void BuildiPhoneResource()
    {
        BuildAssetResource(BuildTarget.iOS);
    }

    [MenuItem("Build/Build Android Resource", false, 101)]
    private static void BuildAndroidResource()
    {
        BuildAssetResource(BuildTarget.Android);
    }

    [MenuItem("Build/Build Windows Resource", false, 102)]
    private static void BuildWindowsResource()
    {
        BuildAssetResource(BuildTarget.StandaloneWindows);
    }

    /// <summary>
    /// 生成绑定素材
    /// </summary>
    private static void BuildAssetResource(BuildTarget target)
    {
        if (Directory.Exists(Util.DataPath))
        {
            Directory.Delete(Util.DataPath, true);
        }

        string streamPath = Application.streamingAssetsPath;
        if (Directory.Exists(streamPath))
        {
            Directory.Delete(streamPath, true);
        }
        Directory.CreateDirectory(streamPath);

        AssetDatabase.Refresh();

        maps.Clear();

        HandleLuaBundle();

        HandleAssetBundle();

        string resPath = "Assets/" + AppConst.AssetDir;
        BuildPipeline.BuildAssetBundles(resPath, maps.ToArray(), BuildAssetBundleOptions.None, target);

        BuildFileIndex();

        string streamDir = Application.dataPath + "/" + AppConst.LuaTempDir;
        if (Directory.Exists(streamDir))
        {
            Directory.Delete(streamDir, true);
        }

        AssetDatabase.Refresh();
    }

    /// <summary>
    /// 处理Lua代码包
    /// </summary>
    private static void HandleLuaBundle()
    {
        string streamDir = Application.dataPath + "/" + AppConst.LuaTempDir;
        if (!Directory.Exists(streamDir))
        {
            Directory.CreateDirectory(streamDir);
        }

        string[] srcDirs = { Application.dataPath + "/Lua/", Application.dataPath + "/ToLua/Lua" };
        for (int i = 0; i < srcDirs.Length; i++)
        {
            CopyLuaBytesFiles(srcDirs[i], streamDir);
        }
        string[] dirs = Directory.GetDirectories(streamDir, "*", SearchOption.AllDirectories);
        for (int i = 0; i < dirs.Length; i++)
        {
            string name = dirs[i].Replace(streamDir, string.Empty);
            name = name.Replace('\\', '_').Replace('/', '_');
            name = "lua/lua_" + name.ToLower() + AppConst.ExtName;

            string path = "Assets" + dirs[i].Replace(Application.dataPath, "");
            AddBuildMap(name, "*.bytes", path);
        }
        AddBuildMap("lua/lua" + AppConst.ExtName, "*.bytes", "Assets/" + AppConst.LuaTempDir);

        AssetDatabase.Refresh();
    }

    /// <summary>
    /// 处理资源包
    /// </summary>
    private static void HandleAssetBundle()
    {
        string resPath = AppDataPath + "/" + AppConst.AssetDir + "/";
        if (!Directory.Exists(resPath))
        {
            Directory.CreateDirectory(resPath);
        }
        //案例
        //AddBuildMap("mp31s" + AppConst.ExtName, "*.mp3", "Assets/Audio/JDBMusic/Base/MP31/");
        //AddBuildMap("mp32s" + AppConst.ExtName, "*.mp3", "Assets/Audio/JDBMusic/Base/MP32/");
        //AddBuildMap("mp33s" + AppConst.ExtName, "*.mp3", "Assets/Audio/JDBMusic/Base/MP33/");
        //AddBuildMap("mp34s" + AppConst.ExtName, "*.mp3", "Assets/Audio/JDBMusic/Base/MP34/");
        //AddBuildMap("mp35s" + AppConst.ExtName, "*.mp3", "Assets/Audio/JDBMusic/Base/MP35/");

        AddBuildMap("noticepanel" + AppConst.ExtName, "*.prefab", "Assets/Prefabs/");
    }

    private static void BuildFileIndex()
    {
        string resPath = AppDataPath + "/StreamingAssets/";
        string newFilePath = resPath + "/files.txt";
        if (File.Exists(newFilePath))
        {
            File.Delete(newFilePath);
        }

        paths.Clear();
        files.Clear();
        Recursive(resPath);

        using (FileStream fs = new FileStream(newFilePath, FileMode.CreateNew))
        {
            using (StreamWriter sw = new StreamWriter(fs))
            {
                for (int i = 0; i < files.Count; i++)
                {
                    string file = files[i];
                    string ext = Path.GetExtension(file);
                    if (file.EndsWith(".meta") || file.Contains(".DS_Store"))
                    {
                        continue;
                    }

                    FileInfo fileInfo = new FileInfo(file);
                    string md5 = Util.GetMD5File(file);
                    string value = file.Replace(resPath, string.Empty);
                    sw.WriteLine(value + "|" + md5 + "|" + fileInfo.Length);
                }
            }
        }
    }

    private static void AddBuildMap(string bundleName, string pattern, string path)
    {
        string[] files = Directory.GetFiles(path, pattern);
        if (files.Length == 0)
        {
            return;
        }

        for (int i = 0; i < files.Length; i++)
        {
            files[i] = files[i].Replace('\\', '/');
        }
        AssetBundleBuild build = new AssetBundleBuild();
        build.assetBundleName = bundleName;
        build.assetNames = files;
        maps.Add(build);
    }

    private static void CopyLuaBytesFiles(string sourceDir, string destDir, bool appendext = true, string searchPattern = "*.lua", SearchOption option = SearchOption.AllDirectories)
    {
        if (!Directory.Exists(sourceDir))
        {
            return;
        }

        string[] files = Directory.GetFiles(sourceDir, searchPattern, option);
        int len = sourceDir.Length;

        if (sourceDir[len - 1] == '/' || sourceDir[len - 1] == '\\')
        {
            --len;
        }

        for (int i = 0; i < files.Length; i++)
        {
            string str = files[i].Remove(0, len);
            string dest = destDir + "/" + str;
            if (appendext)
            {
                dest += ".bytes";
            }
            string dir = Path.GetDirectoryName(dest);
            Directory.CreateDirectory(dir);
            File.Copy(files[i], dest, true);
        }
    }

    /// <summary>
    /// 数据目录
    /// </summary>
    private static string AppDataPath
    {
        get
        {
            return Application.dataPath.ToLower();
        }
    }

    /// <summary>
    /// 遍历目录及其子目录
    /// </summary>
    private static void Recursive(string path)
    {
        string[] names = Directory.GetFiles(path);
        string[] dirs = Directory.GetDirectories(path);
        foreach (string filename in names)
        {
            string ext = Path.GetExtension(filename);
            if (ext.Equals(".meta"))
            {
                continue;
            }
            files.Add(filename.Replace('\\', '/'));
        }
        foreach (string dir in dirs)
        {
            paths.Add(dir.Replace('\\', '/'));
            Recursive(dir);
        }
    }
}
